package org.mtmi.ui.controls.curve;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.mtmi.ui.IMG;
import org.mtmi.ui.M;
import org.mtmi.ui.actions.Action;
import org.mtmi.ui.actions.IAction;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.IContentProvider;
import org.mtmi.ui.controls.ILabelProvider;
import org.mtmi.ui.controls.ListView;
import org.mtmi.ui.controls.ToolBar;
import org.mtmi.ui.controls.listeners.ISelectionListener;
import org.mtmi.ui.controls.listeners.PopupListener;
import org.mtmi.ui.controls.listeners.SelectionEvent;
import org.mtmi.ui.controls.popups.AbstractButtonPopup;
import org.mtmi.ui.controls.popups.TwoButtonsPopup;
import org.mtmi.ui.drawables.IDrawable;
import org.mtmi.ui.drawables.SymbolDrawable;
import org.mtmi.ui.layouts.GridData;
import org.mtmi.ui.layouts.GridLayout;
import org.mtmi.ui.layouts.LayoutData;
import org.mtmi.ui.scenes.COLOR;
import org.mtmi.ui.scenes.Scene;

/**
 * Popup to Edit curves stored in {@link CurveManager}.
 */
public class EditCurvePopup extends AbstractButtonPopup 
  implements ISelectionListener, EditCurve.Listener
{
	
	private static class LabelProvider implements ILabelProvider
	{
		@Override
		public IDrawable getImage(Object element) {
			return ((CurveValueTransformer)element).getDrawable();
		}

		@Override
		public String getText(Object element) {
			//no text here
			return null;
		}
	}
	
	private class ContentProvider implements IContentProvider
	{
		@Override
		public Object[] getElements(Object input) {
			return CurveManager.getCurves();
		}
	}
	
	private class SimpleAction extends Action
	{
		private IDrawable image;
		
		public SimpleAction( IDrawable img ) {
			super( PUSH );
			image = img;
		}
		
		@Override
		public IDrawable getImage() {
			return image;
		}

		@Override
		public boolean isEnabled() {
			return true;
		}

		@Override
		public void run() {
			if( this == a_new ) {
				CurveValueTransformer c = CurveManager.createNewCurve();
				lv_curves.refresh();
				setCurve( c );
			}
			else if( this == a_remove ) {
				TwoButtonsPopup p = new TwoButtonsPopup( getScene(), "Remove the selected curve ?\ncontrol may use it", M.SCENE_EDITOR_CONTROL );
				p.addResponseListener( new PopupListener() {
					@Override
					public void popupButtonSelected(int id) {
						if( id == AbstractButtonPopup.OK ) {
							CurveManager.removeCurve( curr_curve );
							lv_curves.refresh();
							setCurve( null );
						}
					}
				});
			}
			else if( this == a_reset ) {
				curr_curve.reset();
			}
			else if( this == a_reset_rev ) {
				curr_curve.resetReverse();
			}
			else if( this == a_hswap ) {
				curr_curve.swapH();
			}
			else if( this == a_vswap ) {
				curr_curve.swapV();
			}
			redraw();
		}

	}
	
	private EditCurve ed_curve; //the curve currently editing.
	private ListView lv_curves;
	private CurveValueTransformer curr_curve;
	private ToolBar tb_points, tb_curves;
	private IAction a_new, a_remove, a_reset, a_reset_rev, a_hswap, a_vswap;
	
	public EditCurvePopup( Scene scene,int flags ) {
		super( scene, "Edit Curves", flags | M.SCENE_EDITOR_CONTROL );
	}
	
	public void setCurve( CurveValueTransformer c ) {
		curr_curve = c;
		if( ed_curve!=null ) {
			ed_curve.setCurve( c );
			lv_curves.setSelection( c );
			redraw();
		}
	}
	
	public CurveValueTransformer getCurve() { return curr_curve; }
	
	private void createPointActions() {
		tb_points.addAction( a_reset = new SimpleAction( IMG.GetD( IMG.I_CURVE_RESET ) ), false );
		tb_points.addAction( a_reset_rev = new SimpleAction( IMG.GetD( IMG.I_CURVE_RESET_REV ) ), false );
		tb_points.addAction( a_hswap = new SimpleAction( IMG.GetD( IMG.I_CURVE_HSWAP ) ), false );
		tb_points.addAction( a_vswap = new SimpleAction( IMG.GetD( IMG.I_CURVE_VSWAP ) ), true );
	}
	
	private void createCurveActions() {
		tb_curves.addAction( a_new = new SimpleAction( new SymbolDrawable( COLOR.green, SymbolDrawable.PLUS ) ), false );
		tb_curves.addAction( a_remove = new SimpleAction( new SymbolDrawable( COLOR.red, SymbolDrawable.CROSS ) ), true );
	}
	
	@Override
	protected void createButtons() {
		addButton( "Close", OK );
	}
	
	@Override
	public Rectangle createContents( Scene _scene )
	{
		int fe = getFlags()&M.SCENE_EDITOR_CONTROL ;
		
		tb_points = new ToolBar( _scene, fe );
		createPointActions();
		
		tb_curves = new ToolBar( _scene, fe );
		createCurveActions();
		
		ed_curve = new EditCurve( _scene, fe );
		ed_curve.addListener( this );
		
		lv_curves = new ListView( scene, fe);
		lv_curves.addSelectionListener( this );
		lv_curves.setLabelProvider( new LabelProvider() );
		lv_curves.setContentProvider( new ContentProvider() );
		lv_curves.setInput( this );
		
		//layout control:
		GridLayout gl = new GridLayout( 2, false );
		gl.setSpacings( 20 );
		
		Control controls[] = new Control[] {
				tb_points, tb_curves,
				ed_curve,  lv_curves
		};
		
		tb_points.setData( M.D_LAYOUT_DATA, new GridData( M.LEFT, false, M.CENTER, false ) );
		tb_curves.setData( M.D_LAYOUT_DATA, new GridData( M.LEFT, false, M.CENTER, false ) );
		ed_curve.setData( M.D_LAYOUT_DATA, new GridData( M.FILL, true, M.FILL, true ) );
		lv_curves.setData( M.D_LAYOUT_DATA, new GridData( M.FILL, false, M.FILL, true ) );
		
		LayoutData ld = new LayoutData( _scene );
		ld.lw = _scene.getSize().x/2;
		ld.lh = _scene.getSize().y/2;
		Point sz = gl.computeSize( ld, controls );
		
		//center
		ld.lx = (_scene.getSize().x-sz.x)/2;
		ld.ly = (_scene.getSize().y-sz.y)/2;
		
		gl.layout( ld, controls );
		
		if( curr_curve !=null ) {
			ed_curve.setCurve( curr_curve );
			lv_curves.setSelection( curr_curve );
		}
		
//		return new Rectangle( ld.lx, ld.ly, ld.lw, ld.lh );
		return new Rectangle( tb_points.getLocation().x, tb_points.getLocation().y, 
				ed_curve.getSize().x+20+lv_curves.getSize().x,
				tb_points.getSize().y+20+ed_curve.getSize().y );
	}
	
	@Override
	protected void terminate( int id ) {
		lv_curves.dispose();
		ed_curve.dispose();
		tb_points.dispose();
		tb_curves.dispose();
		super.terminate( id );
	}
	
	@Override
	public void selectionChanged( SelectionEvent e ) {
		curr_curve = (CurveValueTransformer)e.selection;
		ed_curve.setCurve( curr_curve );
	}

	@Override
	public void selectionConfirmed(SelectionEvent e) {
		curr_curve = (CurveValueTransformer)e.selection;
		ed_curve.setCurve( curr_curve );
	}

	@Override
	public void pointMoved() {
		//when moving point, see it in the "image" display in list view
		lv_curves.redraw(); 
	}

	
}
